﻿using System;
using System.Globalization;
using System.Threading;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using System.Xml;
using System.Reflection;
using JigLibX.Physics;
using JigLibX.Collision;
using Services;
using Utilities.Menu.UIElements;

using Utilities.Menu;
using System.Collections.ObjectModel;

using Services.Menu;
using Utilities;

using BowMaster.Menu;
using BowMaster.Levels;

namespace BowMaster
{
    public class StateManager : AStateManager
    {
        Game game;
        public GraphicsDeviceManager graphics;
        public ArrayList<ALevel> levels;
        public GameState GameState;
        public OptionsState OptionsState;
        public static int NUMBER_OF_LEVELS = 4;
        //SoundTrackComponent stcomp;
        public StateManager(Game game, GraphicsDeviceManager graphics)
            : base(game, graphics)
        {
            this.game = game;
            this.graphics = graphics;
            int i = 0;
            levels = new ArrayList<ALevel>()
            {
                new StaticTargetTutorial(game,i++),
                new BaloonsTargetTutorial(game,i++),
                new AppleTargetTutorial(game,i++),
                new BaloonsTargetLevel01(game,i++),
                new BaloonsTargetLevel02(game,i++),
                new BaloonsTargetLevel03(game,i++),
                new BaloonsTargetRandom(game)
            };
            NUMBER_OF_LEVELS = levels.Count;
            GameState = Storage.GetGameState();
            OptionsState = Storage.GetOptionsState();
            //for (int i = 0; i < GameState.Records.Count; i++)
            //{
            //    levels[i].recordTime = GameState.Records[i];
            //    levels[i].Available = GameState.Available[i];
            //}
            //stcomp = new SoundTrackComponent(game);
            
        }


        public override void SelectMainMenu()
        {
            Storage.SaveGameState(GameState);
            CleanupComponents();
            game.Components.Add(new MainMenu(game, graphics));
            GC.Collect();
            GC.WaitForPendingFinalizers();

#if WINDOWS || XBOX

            graphics.PreferredBackBufferWidth = 480;
            graphics.PreferredBackBufferHeight = 800;
            graphics.ApplyChanges();
            
#else
            graphics.PreferredBackBufferWidth = 480;
            graphics.PreferredBackBufferHeight = 800;
            graphics.SupportedOrientations = DisplayOrientation.Portrait;
            graphics.ApplyChanges();

#endif
        }

        public void SelectLevelSelectMenu()
        {
            CleanupComponents();
            game.Components.Add(new LevelSelectMenu(game, graphics));
            
            GC.Collect();
            GC.WaitForPendingFinalizers();

#if WINDOWS || XBOX

            graphics.PreferredBackBufferWidth = 480;
            graphics.PreferredBackBufferHeight = 800;
            graphics.ApplyChanges();
            
#else
            graphics.PreferredBackBufferWidth = 480;
            graphics.PreferredBackBufferHeight = 800;
            graphics.SupportedOrientations = DisplayOrientation.Portrait;
            graphics.ApplyChanges();

#endif
        }


        public void SelectOptionsMenu()
        {
            CleanupComponents();
            game.Components.Add(new OptionsMenu(game));

            GC.Collect();
            GC.WaitForPendingFinalizers();

#if WINDOWS || XBOX

            graphics.PreferredBackBufferWidth = 480;
            graphics.PreferredBackBufferHeight = 800;
            graphics.ApplyChanges();

#else
            graphics.PreferredBackBufferWidth = 480;
            graphics.PreferredBackBufferHeight = 800;
            graphics.SupportedOrientations = DisplayOrientation.Portrait;
            graphics.ApplyChanges();

#endif
        }

        public void SelectCreditsMenu()
        {
            CleanupComponents();

            game.Components.Add(new CreditsMenu(game));
            GC.Collect();
            GC.WaitForPendingFinalizers();

#if WINDOWS || XBOX

            graphics.PreferredBackBufferWidth = 480;
            graphics.PreferredBackBufferHeight = 800;
            graphics.ApplyChanges();

#else
            graphics.PreferredBackBufferWidth = 480;
            graphics.PreferredBackBufferHeight = 800;
            graphics.SupportedOrientations = DisplayOrientation.Portrait;
            graphics.ApplyChanges();
#endif
        }
        public void SelectLevel(int index)
        {
            if (index < 0 || index >= levels.Count) return;

            CleanupComponents();

            if (game.IsTrial() && index>=8)
            {
                SelectCreditsMenu();
                return;
            }

            GameState.Current_level = index;

#if WINDOWS || XBOX

            graphics.PreferredBackBufferWidth = 800;
            graphics.PreferredBackBufferHeight = 480;
            graphics.ApplyChanges();

#else
            graphics.PreferredBackBufferWidth = 800;
            graphics.PreferredBackBufferHeight = 480;
            graphics.SupportedOrientations =  DisplayOrientation.Default;
            graphics.ApplyChanges();

#endif

            levels[index].Reset();
            
            game.Components.Add(levels[index]);
            //GC.Collect();
            //GC.WaitForPendingFinalizers();


        }

        public void Resume()
        {
            SelectLevel(GameState.Current_level);
        }

        public void SelectNextLevel()
        {
            //levels[GameState.Current_level].Available = true;
            levels[GameState.Current_level].level_ended = true;
            int newRecord = levels[GameState.Current_level].shoots;
            //newRecord = (float)Math.Round(newRecord, 2);
            if (GameState.Records[GameState.Current_level] >= newRecord)
                GameState.Records[GameState.Current_level] = newRecord;
            GameState.Available[GameState.Current_level] = true;

            if (GameState.Current_level + 1 >= levels.Count)
                SelectCreditsMenu();
            else
            {
                GameState.Current_level++;
                Resume();
            }
            Storage.SaveGameState(GameState);
            
        }
        public void SelectPrevLevel()
        {
            levels[GameState.Current_level].level_ended = true;
            if (GameState.Current_level - 1 >= 0)
                GameState.Current_level--;
            Storage.SaveGameState(GameState);
            Resume();
        }
        public void ResetGameState()
        {
            GameState = Storage.ResetGameState();
        }

        
    }
    
}
